package online.foxnull2.foxmall.auth.web;

import com.alibaba.fastjson.TypeReference;
import online.foxnull2.common.constant.AuthConstant;
import online.foxnull2.common.exception.BizCodeEnum;
import online.foxnull2.common.utils.R;
import online.foxnull2.common.vo.MemberRespVo;
import online.foxnull2.foxmall.auth.feign.MemberFeginService;
import online.foxnull2.foxmall.auth.feign.OSSFeginService;
import online.foxnull2.foxmall.auth.vo.UserLoginVo;
import online.foxnull2.foxmall.auth.vo.UserRegisterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Controller
public class LoginOrRegisterController {

    private final OSSFeginService ossFeginService;
    private final StringRedisTemplate stringRedisTemplate;
    private final MemberFeginService memberFeginService;

    @Autowired
    public LoginOrRegisterController(OSSFeginService ossFeginService,
                                     StringRedisTemplate stringRedisTemplate,
                                     MemberFeginService memberFeginService) {
        this.ossFeginService = ossFeginService;
        this.stringRedisTemplate = stringRedisTemplate;
        this.memberFeginService = memberFeginService;
    }

    @ResponseBody
    @GetMapping("/mail/sendCode")
    public R sendCode(@RequestParam("email") String email) {
        String code = stringRedisTemplate.opsForValue().get(AuthConstant.EMAIL_CODE_CACHE_PREFIX + email);
        if (!ObjectUtils.isEmpty(code)) {
            long time = Long.parseLong(code.split("_")[1]);
            if (System.currentTimeMillis() - time < 60000) {
                return R.error(BizCodeEnum.EMAIL_CODE_EXCEPTION.getCode(), BizCodeEnum.EMAIL_CODE_EXCEPTION.getMsg());
            }
        } else {
            code = UUID.randomUUID().toString().substring(0, 5);
            ossFeginService.sendSimpleMessage(email, "Foxmall Code", code);
            stringRedisTemplate.opsForValue().set(AuthConstant.EMAIL_CODE_CACHE_PREFIX + email,
                    code + "_" + System.currentTimeMillis(),
                    10, TimeUnit.MINUTES);
        }
        return R.ok();
    }

    @PostMapping("/register")
    public String register(@Valid UserRegisterVo userRegisterVo, BindingResult result,
                           RedirectAttributes redirectAttributes) {
        if (result.hasErrors()) {
            Map<String, String> errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField,
                    (fieldError) -> !ObjectUtils.isEmpty(fieldError.getDefaultMessage()) ? fieldError.getDefaultMessage() : ""));
            redirectAttributes.addFlashAttribute("errros", errors);
            return "redirect:http://auth.foxmall.com/register.html";
        }
        String authCode = userRegisterVo.getCode();
        String codeTime = stringRedisTemplate.opsForValue().get(AuthConstant.EMAIL_CODE_CACHE_PREFIX + userRegisterVo.getEmail());
        if (!ObjectUtils.isEmpty(codeTime) && authCode.equalsIgnoreCase(codeTime.split("_")[0])) {
            stringRedisTemplate.delete(AuthConstant.EMAIL_CODE_CACHE_PREFIX + userRegisterVo.getEmail());
            R r = memberFeginService.register(userRegisterVo);
            if (Objects.equals(r.get("code").toString(), "0")) {
                return "redirect:http://auth.foxmall.com/login.html";
            } else {
                Map<String, String> errors = new HashMap<>();
                errors.put("msg", r.get("msg").toString());
                redirectAttributes.addFlashAttribute("errors", errors);
                return "redirect:http://auth.foxmall.com/register.html";
            }
        } else {
            Map<String, String> errors = new HashMap<>();
            errors.put("code", "code invalid");
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.foxmall.com/register.html";
        }
    }

    @PostMapping("/login")
    public String login(UserLoginVo userLoginVo, RedirectAttributes redirectAttributes, HttpSession session, HttpServletRequest request) {
        System.out.println(request.getServerName());
        System.out.println(request.getServerPort());
        R r = memberFeginService.login(userLoginVo);
        if (Objects.equals(r.get("code").toString(), "0")) {
            MemberRespVo memberRespVo = r.getObj(new TypeReference<>() {
            });
            session.setAttribute(AuthConstant.LOGIN_USER, memberRespVo);
            return "redirect:http://foxmall.com";
        } else {
            Map<String, String> errors = new HashMap<>();
            errors.put("msg", r.get("msg").toString());
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.foxmall.com/login.html";
        }
    }

    @GetMapping("/login.html")
    public String loginPage(HttpSession session) {
        if (!ObjectUtils.isEmpty(session.getAttribute(AuthConstant.LOGIN_USER))) {
            return "redirect:http://foxmall.com";
        }
        return "login";
    }
}
